package com.bungarus.device.model;

import com.bungarus.device.codec.protobuf.DeviceProtobuf;
import com.bungarus.device.codec.protobuf.DeviceServiceGrpc;
import io.grpc.stub.StreamObserver;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class DeviceGrpcService extends DeviceServiceGrpc.DeviceServiceImplBase {
    Logger logger = Logger.getLogger(DeviceGrpcService.class);

    private DeviceServiceImpl service;

    @Autowired
    public DeviceGrpcService(DeviceServiceImpl service) {
        this.service = service;
    }

    /**
     * register device when user logged in
     * if the same device type exists, compare the device name, if is not identical, update it with new one
     * @param request
     * @param responseObserver
     */
    @Override
    public void registerDevice(DeviceProtobuf.RegisterDeviceRequest request, StreamObserver<DeviceProtobuf.OpResultReply> responseObserver) {
        DeviceProtobuf.DeviceInfo deviceInfo = request.getDeviceInfo();
        logger.info("client message received: " + deviceInfo);

        Device device = deviceInfo2Device(deviceInfo);
        int code = service.registerDevice(device);

        responseObserver.onNext(DeviceProtobuf.OpResultReply.newBuilder().setCode(200).build());
        responseObserver.onCompleted();
    }

    /**
     * get all valid devices for specified member
     */
    @Override
    public void getDeviceList(DeviceProtobuf.DeviceListRequest request, StreamObserver<DeviceProtobuf.DeviceListReply> responseObserver) {
        logger.info("client message received: " + request.getTid() + "," + request.getApp() + "," + request.getMid());

        DeviceProtobuf.DeviceListReply.Builder builder = DeviceProtobuf.DeviceListReply.newBuilder();

        List<Device> deviceList = service.getDeviceList(request.getTid(), request.getApp(), request.getMid());
        for(Device device:deviceList){
            builder.addDeviceInfo(device2DeviceInfo(device));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * Convert Device to DeviceInfo
     * @param device
     * @return
     */
    private DeviceProtobuf.DeviceInfo device2DeviceInfo(Device device){
        return DeviceProtobuf.DeviceInfo.newBuilder()
                .setTid(device.getTenantId())
                .setMid(device.getMid())
                .setApp(device.getApp())
                .setType(String.valueOf(device.getType()))
                .setName(device.getName())
                .build();
    }

    /**
     * Convert DeviceInfo to Device
     * @param deviceInfo
     * @return
     */
    private Device deviceInfo2Device(DeviceProtobuf.DeviceInfo deviceInfo){
        Device device = new Device();
        device.setTenantId(deviceInfo.getTid());
        device.setMid(deviceInfo.getMid());
        device.setApp(deviceInfo.getApp());
        device.setType(Integer.parseInt(deviceInfo.getType()));
        device.setName(deviceInfo.getName());
        return device;
    }
}
